<template>
  <el-dialog v-model="dialogVisible" title="日报" draggable @closed="handlerClosed">
    <div class="btn-group">
      <div class="tt">{{ utils.formatDate(selectedDate, 'yyyy-MM-dd') }}</div>
      <div class="btn-cells">
        <el-button type="danger" :icon="Delete" @click="handleClickBtnDeleteAllTimelog">清空</el-button>
      </div>
    </div>
    <div class="content-bd">
      <div class="content-bd-timeline">
        <TimeSlider v-if="dialogVisible" ref="timeSlider" :time-dates="timeDates" :today="todayInfo.date" :timelogCategory="projectTypes" :begin-time="beginTime" :end-time="endTime" :disabled-times="disabledTimes" :logList="timelineList" @checked="handleCheckedTimeSlider" @delete-cell="handleDeleteCellTimeSlider" />
      </div>
    </div>
    <DialogAddTimelog ref="dialogAddTimelog" :project-types="projectTypes" :tilelogDate="selectedDate" :occupiedTimeSlots="occupiedTimeSlots" @submited="handleSubmited" @closed="handlerClosed" />
  </el-dialog>
</template>
<script setup lang="ts">
import { ref, nextTick } from 'vue'
import * as utils from '../../utils'
import { Delete } from '@element-plus/icons-vue'
import { useTaskTypeStore, useUsersStore } from '../../stores'
import TimeSlider from '../../components/Timelog/TimeSlider.vue'
import DialogAddTimelog from '../../components/dialog/DialogAddTimelog.vue'
import http from '../../http'
import { ElMessage, ElMessageBox } from 'element-plus'

const usersStore = useUsersStore()
const dialogVisible = ref(false)
const selectedDate = ref(new Date())
const timelogFullData = ref()
const timeDates = ref<any[]>(['08:00', '09:00', '10:00', '11:00', '12:00', '13:00', '14:00', '15:00', '16:00', '17:00', '18:00', '19:00', '20:00', '21:00'])
const disabledTimes = ref<any[]>(['08:00', '09:00', '13:00', '16:00'])
const beginTime = ref('08:00')
const endTime = ref('16:50')
const todayInfo = ref<any>({ data: '' })
const projectTypes = ref<any[]>(useTaskTypeStore().getAllState())
const timelineList = ref([])
const occupiedTimeSlots = ref<any[]>([])
const valueCalendar = ref(new Date())
const flagContent = ref(false)
const timelogList = ref()
const dialogAddTimelog = ref()

/**
 * 处理对话框关闭事件
 *
 * 当对话框关闭时，调用此方法将 dialogVisible 的值设置为 false，隐藏对话框。
 */
const handlerClosed = () => {
  dialogVisible.value = false
}

const handleCheckedTimeSlider = (items: any) => {
  // console.log('handleCheckedTimeSlider', items)
  handleClickBtnOpenDialog(items)
}
const handleClickBtnDeleteAllTimelog = () => {
  // 清空当日所有打卡记录
}
/**
 * 设置时间线和今日信息
 *
 * @param val 日期对象
 */
function setTimelineAndTodayInfo(val: Date) {
  const date = utils.formatDate(val, 'yyyy-MM-dd')
  const item = timelogFullData.value.filter((item: any) => {
    return item.timelogDate === date
  })
  nextTick(() => {
    timelineList.value = item || []
  })

  const { startWorkTime, endWorkTime, startLunchTime, endLunchTime } = usersStore.getAllState() as any
  todayInfo.value = {
    date,
    startWorkTime,
    endWorkTime,
    startLunchTime,
    endLunchTime,
  }
  beginTime.value = startWorkTime
  endTime.value = endWorkTime
}
/**
 * 检查日期
 *
 * @param day 日期对象
 * @returns 无返回值
 */
const checkDay = (day: Date) => {
  const date = utils.formatDate(day, 'yyyy-MM-dd')
  selectedDate.value = day
  setTimelineAndTodayInfo(day)
  const [today, twoWeeksAgo] = utils.getTodayAndPreviousTwoWeeks(new Date())

  // 不限定时间 可用时间段
  flagContent.value = utils.isDateBetween(utils.formatDate(twoWeeksAgo, 'yyyy-MM-dd'), utils.formatDate(today, 'yyyy-MM-dd'), date)
  flagContent.value = true

  // 检查 当前日期 可用时间段
  occupiedTimeSlots.value = timelineList.value.map((item: any) => `${item.startTime.split(' ')[1]} - ${item.endTime.split(' ')[1]}`)
}
/**
 * 处理表单提交
 *
 * @async
 */
const handleSubmited = async () => {
  setTimeout(async () => {
    await getTimelog()
    nextTick(() => {
      checkDay(new Date(selectedDate.value))
    })
  }, 1000)
}

/**
 * 获取当月的第一天和最后一天
 *
 * @returns 返回包含两个Date对象的数组，第一个为当月第一天，第二个为当月最后一天
 */
const getMonthStartAndEnd = (now: Date = new Date()) => {
  // 获取当前日期
  const currentYear = now.getFullYear()
  const currentMonth = now.getMonth() // 注意：JavaScript中月份是从0开始的，即0代表1月

  // 设置当月的第一天
  const firstDayOfMonth = new Date(currentYear, currentMonth, 1)

  // 获取当月的最后一天日期（下一个月的第一天减去1天）
  const lastDayOfMonth = new Date(currentYear, currentMonth + 1, 0)

  // 返回包含第一天和最后一天Date对象的数组
  return [firstDayOfMonth, lastDayOfMonth]
}
/**
 * 获取时间日志列表
 *
 * @returns Promise<void>
 */
const getTimelog = async () => {
  const [start, end] = getMonthStartAndEnd(valueCalendar.value)
  const res = await http({
    path: '/dev-api/oa/timelog/list',
    method: 'GET',
    params: {
      userName: usersStore.user.username,
      pageSize: 99999,
      startTimelogDate: utils.formatDate(start, 'yyyy-MM-dd'),
      endTimelogDate: utils.formatDate(end, 'yyyy-MM-dd'),
    },
  })
  timelogFullData.value = res.rows
  timelogList.value = convertListToObject(res.rows)
  console.log('timelog', res)
  // console.log('timelogList.value', timelogList.value)
}

/**
 * 将记录数组转换为日期与百分比的映射对象
 *
 * 此函数接收一个记录数组，每个记录包含一个日期和对应的百分比
 * 它将这些记录转换为一个对象，其中日期为键，百分比为值
 * 这样可以在O(1)时间复杂度内快速访问特定日期的百分比
 *
 * @param records 记录数组，每个元素包含日期和百分比信息
 * @returns 一个对象，键为日期，值为对应的百分比
 */
function convertListToObject(records: []): Record<string, number> {
  // console.log('records', records)
  // 初始化一个空对象来存储日期与百分比的映射
  const result: Record<string, any> = {}

  // 遍历记录数组
  records.forEach((record: any) => {
    const date = record.timelogDate
    const duration = record.durationTime
    // 将记录的日期作为键，百分比作为值，存储到结果对象中
    if (result[date]) {
      result[date] += duration
    } else {
      result[date] = duration
    }
  })

  return result
}
/**
 * 点击按钮打开对话框
 *
 * @param item 要传入的参数
 */
const handleClickBtnOpenDialog = (item: any) => {
  const workTime: any[] = []
  timelineList.value.forEach((e: any) => {
    // workTime.push(`${e.startTime.slice(-5)} - ${e.endTime.slice(-5)}`)
    workTime.push([new Date(e.startTime), new Date(e.endTime)])
  })
  // console.log('点击按钮打开对话框 item', [item[0].value, item[1].value], workTime)

  dialogAddTimelog.value?.openDialog([item[0].value, item[1].value], workTime)
}
const handleDeleteCellTimeSlider = (ids: any[], type: string = 'all') => {
  const doDay = utils.formatDate(selectedDate.value, 'yyyy-MM-dd')
  let msg = `确定删除 ${doDay} 所有日报吗？`
  if (type !== 'all') {
    msg = `确定删除记录吗？`
  }

  ElMessageBox.confirm(msg, '提示')
    .then(async () => {
      // 确认删除
      await deleteTimelogByIds(ids.join(','))
      ElMessage({
        type: 'success',
        message: `成功删除 ${ids.length} 条记录！`,
      })
    })
    .catch(() => {})
}
const openDialog = (date: Date) => {
  console.log('openDialog', {})
  dialogVisible.value = true
  checkDay(date)
  getTimelog()
}

const deleteTimelogByIds = async (ids: string) => {
  const res = await http({
    method: 'DELETE',
    path: '/dev-api/oa/timelog/' + ids,
    params: {},
  })
  const { code } = res
  if (code === 200) {
    await getTimelog()
    // console.log('Delete', code)
    nextTick(() => {
      checkDay(new Date(selectedDate.value))
    })
  }
}
defineExpose({ openDialog })
</script>
<style lang="scss" scoped>
.content-bd {
  flex: 1;
  height: 500px;
  position: relative;
  .content-bd-timeline {
    overflow: auto;
    height: calc(100% - 20px);
    position: absolute;
    padding-right: 10px;
    width: 100%;
  }
}
</style>
